home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / BlobMgr / Blob Manager Demo 4 / DemoSwap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-17  |  4.8 KB  |  240 lines  |  [TEXT/MACA]

  1. /*
  2.     Blob Manager Demonstration:  Coin Swap module
  3.  
  4.     This has a linear board with either 5, 7 or 9 pieces.  The middle
  5.     piece is always empty, the pieces on one end are filled with black
  6.     coins, the pieces on the other end are filled with white coins.
  7.     The object is to swap the coins.  A coin can slide into an empty
  8.     piece next to it, or jump over a single coin to land on an empty
  9.     piece.
  10.  
  11.     A menu allows the number of coins to be chosen.  To win, the coins
  12.     have to be swapped in a specific number of moves.
  13.  
  14.     26 July 1986        Paul DuBois
  15. */
  16.  
  17.  
  18. # include    "BlobDemo.h"
  19. # include    <MenuMgr.h>
  20.  
  21. # define    vMessage    10
  22. # define    vPiece        30
  23. # define    maxPieces    9
  24. # define    pieceSize    24
  25. # define    pieceGap    1
  26.  
  27.  
  28. static GrafPtr            swapPort;
  29. static MenuHandle        cnfgMenu;
  30. static BlobSetHandle    donors = nil;
  31. static BlobSetHandle    receptors = nil;
  32. static int                hMid;
  33. static Str255            statusStr = "\p";
  34.  
  35. static int                nPieces = 5;
  36. static int                nMoves = 8;
  37. static BlobHandle        piece[maxPieces];
  38. static int                moves;
  39. static Boolean            pause;
  40.     
  41.  
  42. static StatusMesg (s)
  43. Str255    s;
  44. {
  45. Rect    r;
  46.  
  47.     SetRect (&r, hMid - 60, vMessage, hMid + 60, vMessage+16);
  48.     TextBox    (s+1, (long) s[0], &r, 1);
  49.     StrCpy (statusStr, s);
  50. }
  51.  
  52.  
  53. /*
  54.     Reset to start state.  This recreates the board each time.  All the
  55.     blobs in the board require explicit matches except the middle one.
  56. */
  57.  
  58. static Reset ()
  59. {
  60. BlobHandle    b;
  61. Rect        r;
  62. int            i, h;
  63. Str255        s;
  64.  
  65.     InvalRect (&swapPort->portRect);    /* force update when done resetting */
  66.     pause = false;
  67.     moves = nMoves;
  68.     MovesLeft (moves, s);
  69.     StatusMesg (s);
  70.  
  71.     if (receptors != nil)                /* clobber any existing receptor set */
  72.     {
  73.         HideBlobSet (receptors);
  74.         DisposeBlobSet (receptors);
  75.     }
  76.     receptors = NewBlobSet ();
  77.  
  78.     h = hMid - (nPieces * (pieceSize + pieceGap) - pieceGap) / 2;
  79.     for (i = 0; i < nPieces; ++i)
  80.     {
  81.         b = NewBlob (receptors, false, 0, i != (nPieces - 1) / 2, 0L);
  82.         piece[i] = b;
  83.         OpenBlob ();
  84.         SetRect (&r, h, vPiece, h + pieceSize, vPiece + pieceSize);
  85.         EraseRect (&r);
  86.         FrameRect (&r);
  87.         CloseRectBlob (b, &r, &r);
  88.         h += pieceSize + pieceGap;
  89.         if (i < (nPieces - 1) / 2)
  90.         {
  91.             GlueGlob (GetBlobHandle (donors, 0), b);
  92.             NewBlobMatch (GetBlobHandle (donors, 1), b);
  93.         }
  94.         else if (i > (nPieces - 1) / 2)
  95.         {
  96.             GlueGlob (GetBlobHandle (donors, 1), b);
  97.             NewBlobMatch (GetBlobHandle (donors, 0), b);
  98.         }
  99.     }
  100.     EnableBlobSet (receptors);
  101. }
  102.  
  103.  
  104. static SwapPause (msg)
  105. StringPtr    msg;
  106. {
  107.     StatusMesg (msg);
  108.     pause = true;
  109. }
  110.  
  111.  
  112. static Mouse (pt, t, mods)
  113. Point    pt;
  114. long    t;
  115. int        mods;
  116. {
  117. Str255            s;
  118. register int    i;
  119.  
  120. /*
  121.     Freeze all the pieces that can't be moved, then call BlobClick.
  122. */
  123.     for (i = 0; i < nPieces; ++i)
  124.     {
  125.         ThawBlob (piece[i]);
  126.         if (BGlob (piece[i]) == nil) continue;
  127.         if (i > 0 && BGlob (piece[i-1]) == nil) continue;
  128.         if (i > 1 && BGlob (piece[i-2]) == nil) continue;
  129.         if (i < nPieces - 1 && BGlob (piece[i+1]) == nil) continue;
  130.         if (i < nPieces - 2 && BGlob (piece[i+2]) == nil) continue;
  131.         FreezeBlob (piece[i]);
  132.     }
  133.     if (!pause)
  134.     {
  135.         BlobClick (pt, t, donors, receptors);
  136.         if (BClickResult () == bcXfer)
  137.         {
  138.             if (--moves == 0)
  139.             {
  140.                 if (BlobSetQuiet (receptors))
  141.                     SwapPause ("\pYou Win");
  142.                 else
  143.                     SwapPause ("\pYou Lose");
  144.             }
  145.             else
  146.             {
  147.                 MovesLeft (moves, s);
  148.                 StatusMesg (s);
  149.             }
  150.         }
  151.     }
  152. }
  153.  
  154.  
  155. /*
  156.     Select configuration:  4, 6, or 8 coins (2, 3, or 4 on each side).
  157.     If the number of coins on each side is n, the number of moves
  158.     to solve is (n+1)^2 - 1.
  159. */
  160. DoConfiguration (item)
  161. int        item;
  162. {
  163.     nPieces = 2 * item + 3;            /* 1->5, 2->7, 3->9 pieces */
  164.     nMoves = (item + 2) * (item + 2) - 1;
  165.     Reset ();
  166. }
  167.  
  168.  
  169. static Activate (active)
  170. Boolean    active;
  171. {
  172.     if (active)
  173.     {
  174.         SetDragRects (swapPort);
  175.         SetBCPermissions (false, true, false, false, false);    /* xfer only */
  176.         cnfgMenu = GetMenu (swapCnfgMenuRes);
  177.         SkelMenu (cnfgMenu, DoConfiguration, DoMClobber);
  178.     }
  179.     else
  180.         SkelRmveMenu (cnfgMenu);
  181. }
  182.  
  183.  
  184. static Update (resized)
  185. Boolean    resized;
  186. {
  187.     DrawBlobSet (receptors);
  188.     StatusMesg (statusStr);
  189. }
  190.  
  191.  
  192. /*
  193.     Make donor blobs.
  194. */
  195.  
  196. static MakeDonors ()
  197. {
  198. BlobHandle    b;
  199. Rect        r;
  200.  
  201.     donors = NewBlobSet ();
  202.     b = NewBlob (donors, false, infiniteGlue, false, 0L);
  203.     OpenBlob ();
  204.     SetRect (&r, 0, 0, pieceSize, pieceSize);
  205.     EraseRect (&r);
  206.     FrameRect (&r);
  207.     InsetRect (&r, 2, 2);
  208.     PaintOval (&r);
  209.     InsetRect (&r, -2, -2);
  210.     CloseRectBlob (b, &r, &r);
  211.     b = NewBlob (donors, false, infiniteGlue, false, 0L);
  212.     OpenBlob ();
  213.     PaintRect (&r);
  214.     InsetRect (&r, 2, 2);
  215.     EraseOval (&r);
  216.     InsetRect (&r, -2, -2);
  217.     CloseRectBlob (b, &r, &r);
  218. }
  219.  
  220.  
  221. SwapInit    ()
  222. {
  223.     SkelWindow (swapPort = GetDemoWind (swapWindRes),
  224.                 Mouse,            /* mouse clicks */
  225.                 nil,            /* key clicks */
  226.                 Update,            /* updates */
  227.                 Activate,        /* activate/deactivate events */
  228.                 nil,            /* close window */
  229.                 DoWClobber,        /* dispose of window */
  230.                 nil,            /* idle proc */
  231.                 false);            /* irrelevant, since no idle proc */
  232.  
  233.     hMid = swapPort->portRect.right / 2;
  234.  
  235.     MakeDonors ();
  236.     Reset ();
  237.     Update ();
  238.     ValidRect (&swapPort->portRect);
  239. }
  240.